/*
 * Utils.cpp
 */

#include "Utils.h"

float Utils::PI = 3.141592654;

string* Utils::stringTokenize(string str, char delimiter, int& tokenCount) {
	string* tokens = new string[8];
	string token = "";
	int j = 0;
	for (unsigned int i = 0; i < str.size() ; i++) {
		if (str[i] == delimiter && j < 8) {
			if (token.size() > 0) {
				tokens[j] = token;
				j++;
				tokenCount++;
				token = "";
			}
		} else {
			token = token + str[i];
		}
		if (j > 7) {
			tokenCount++;
			return tokens;
		}
	}
	if (token.size() > 0) {
		tokens[j] = token;
		tokenCount++;
	}
	return tokens;
}

float Utils::toDeg(float rad){
	return (rad * 360) / (2*PI);
}

float Utils::abs(float a){
	if (a > 0){
		return a;
	} else {
		return -a;
	}
}

bool Utils::esPar(int numero) {
	float residuo = numero % 2;
	if (residuo == 0) return true;
	return false;
}

int Utils::round (float value) {
	int trunk = (int)value;
	if (abs(value - trunk) >= 0.5) {
		if (trunk < 0) return trunk - 1;
		else return trunk + 1;
	}
	return trunk;
}

float Utils::min(float arg1, float arg2){
	float result = arg1;

	if (result > arg2){
		result = arg2;
	}

	return result;
}

int Utils::min(int arg1, int arg2, int arg3, int arg4){
	int result = arg1;

	if (result > arg2){
		result = arg2;
	}

	if (result > arg3){
		result = arg3;
	}

	if (result > arg4 ){
		result = arg4;
	}

	return result;
}

int Utils::max(int arg1, int arg2){
	int result = arg1;

	if (result < arg2){
		result = arg2;
	}
	return result;
}

int Utils::max(int arg1, int arg2, int arg3, int arg4){
	int result = arg1;

	if (result < arg2){
		result = arg2;
	}

	if (result < arg3){
		result = arg3;
	}

	if (result < arg4 ){
		result = arg4;
	}

	return result;
}


float Utils::stringToFloat(string s){
	float value;
	istringstream str(s);
	str >> value;
	return value;
}

int Utils::stringToInt(string s){
	stringstream buffer(s);
	int value;
	buffer >> value;
	return value;
}

bool Utils::validatePositiveInt(string s) {
	int value;
	for (unsigned int i = 0; i < s.size(); i++){
		value = (int)s[i];
		if ((value < 48) || (value > 57)) return false; 
	}
	return true;
}

bool Utils::validateFloat(string s) {
	int value;
	int dots = 0;
	for (unsigned int i = 0; i < s.size(); i++){
		value = (int)s[i];
		if (value != 13){
			if ((((value < 44) || (value > 57)) || (value == 47)) || ((value == 45) && (i > 0)))
				return false;
		}
		if ((value == 44) || (value == 46)) dots++;
		if (dots > 1) return false; 
	}
	return true;
}

bool Utils::validateAddressRange(string s) {
	int value;
	int separators = 0;
	for (unsigned int i = 0; i < s.size(); i++){
		value = (int)s[i];
		if (value != 13){
			if ((((value < 48) || (value > 57)) && (value != 45)) || ((value == 45) && ((i == 0) || (i == s.size()-1))))
				return false;
		}
		if (value == 45) separators++;
		if (separators > 1) return false; 
	}
	return true;
}

void Utils::comaToDot(string& s) {
		for (unsigned int i = 0; i < s.size(); i++){
			if (s[i] == ',') s[i] = '.';
		}
}

string Utils::negativeToPositive(string s) {
	string str = "";
	for (unsigned int i = 0; i < (s.size()-1); i++){
		str = str + s[i+1];
	}
return str;
}

string Utils::intToString(int i) {
	std::stringstream str;
	str << i;
	return (str.str());
}

int* Utils::stringAddressTokenize(string str, char addressRangeSeparator)
{
	int* address = new int[2];
	string token = "";
	int j = 0;
	for (unsigned int i = 0; i < str.size() ; i++) {
		if (str[i] == addressRangeSeparator) {
			if (token.size() > 0) {
				address[j] = Utils::stringToInt(token);
				j++;
				token = "";
			}
		} else {
			token = token + str[i];
		}
	}
	if (token.size() > 0) {
		address[j] = Utils::stringToInt(token);
	}
	return address;
}

bool Utils::validateWayType(string s) {
	if ((s != "calle") && (s != "avenida") && (s != "autopista")) return false;
	return true;
}
	
bool Utils::validateObjectType(string s) {
	if ((s != "hotel") && (s != "restaurant") && (s != "comisaria") && (s != "escuela") && (s != "hospital")) return false;
	return true;
}

string Utils::getConfigurationValue(string key) {
	ifstream file;
	file.open(CONFIGURATION_PATH, ifstream::out);
	if (file.is_open()) {
		string line;
		while (!file.eof()) {
			getline(file, line);
			int tokenCount = 0;
			string* tokens = Utils::stringTokenize(line, ';', tokenCount);
			if (tokenCount != 2) {
				file.close();
				return "";
			}
			if (tokens[0].compare(key.c_str()) == 0) {
				file.close();
				return tokens[1];
			}
		}
	} else {
		std::cout << "No se pudo abrir " << CONFIGURATION_PATH <<". Valor por defecto - ";
		char* defViewX = "800";
		char* defViewY = "600";
		char* defResX = "800";
		char* defResY = "600";

		if (strcmp(key.c_str(), "ViewportX") == 0){
			std::cout << "ViewportX = " << defViewX << std::endl;
			return defViewX;
		} else 
			if (strcmp(key.c_str(), "ViewportY") == 0){
				std::cout << "ViewportY = " << defViewY << std::endl;
				return defViewY;
			}
		else 
			if (strcmp(key.c_str(), "ResolutionX") == 0){
				std::cout << "ResolutionX = " << defResX << std::endl;
				return defResX;
			}
			else if (strcmp(key.c_str(), "ResolutionY") == 0){
				std::cout << "ResolutionY = "<< defResY << std::endl;
				return defResX;
			} else {
				std::cout << std::endl;
			}
	}
	file.close();
	return "";
}
